
#ifndef pthread_once_SINGLETON_H
#define pthread_once_SINGLETON_H

#include <pthread.h>
#include <stdlib.h> // atexit

template<typename T>
class Singleton
{
public:
	static T& instance()
	{
		pthread_once(&_ponce, &Singleton::init);
		return *_value;
	}

private:
	Singleton();
	~Singleton();
	Singleton(const Singleton&);
	Singleton& operator=(const Singleton&);

	static void init()
	{
		_value = new T();
		::atexit(destroy);
	}

	static void destroy()
	{
		delete _value;
	}

private:
	static pthread_once_t _ponce;
	static T*             _value;
};

template<typename T>
pthread_once_t Singleton<T>::_ponce = PTHREAD_ONCE_INIT;

template<typename T>
T* Singleton<T>::_value = NULL;

#endif

